home *** CD-ROM | disk | FTP | other *** search
/ Sprite 1984 - 1993 / Sprite 1984 - 1993.iso / src / X11R4 / cmds / X / ddx / Xmfbpmax / mfbpmax_io.c < prev    next >
Encoding:
C/C++ Source or Header  |  1991-02-20  |  20.8 KB  |  935 lines

  1. /***********************************************************
  2. Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts,
  3. and the Massachusetts Institute of Technology, Cambridge, Massachusetts.
  4.  
  5.                         All Rights Reserved
  6.  
  7. Permission to use, copy, modify, and distribute this software and its 
  8. documentation for any purpose and without fee is hereby granted, 
  9. provided that the above copyright notice appear in all copies and that
  10. both that copyright notice and this permission notice appear in 
  11. supporting documentation, and that the names of Digital or MIT not be
  12. used in advertising or publicity pertaining to distribution of the
  13. software without specific, written prior permission.  
  14.  
  15. DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
  16. ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
  17. DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
  18. ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
  19. WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
  20. ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
  21. SOFTWARE.
  22.  
  23. ******************************************************************/
  24.  
  25. /* $XConsortium: mfbpmax_io.c,v 1.13 90/01/19 14:56:36 keith Exp $ */
  26. /* $Id: mfbpmax_io.c,v 1.3 91/02/19 21:34:28 kupfer Exp $ */
  27.  
  28. #include <stdio.h>
  29. #include <sys/types.h>
  30. #include <sys/file.h>
  31. #include <sys/time.h>
  32. #ifdef sprite
  33. #include <dev/graphics.h>
  34. #include <sys/ioctl.h>
  35. #endif
  36. #include <sys/tty.h> 
  37. #include <errno.h>
  38. #include <sys/devio.h> 
  39. #include <machine/pmioctl.h>
  40. #include <machine/dc7085cons.h>
  41.  
  42. #include "misc.h"
  43. #include "X.h"
  44. #define NEED_EVENTS
  45. #include "Xproto.h"
  46. #include "scrnintstr.h"
  47. #include "pixmapstr.h"
  48. #include "input.h"
  49. #include "cursorstr.h"
  50. #include "regionstr.h"
  51. #include "colormap.h"
  52. #include "resource.h"
  53. #include "servermd.h"
  54. #include "dixstruct.h"
  55.  
  56. #include "mi.h"
  57. #include "mfb.h"
  58. #include "pm.h"
  59.  
  60.  
  61. void pmQueryBestSize();
  62.  
  63. /*
  64.  * These "statics" imply there will never be more than one "pm" display and
  65.  * mouse attached to a server; otherwise, they would be in SCREEN private info.
  66.  *
  67.  * This is probably the case since the Ultrix driver does not allow one to
  68.  * open the display without also getting at the same file descriptor that
  69.  * handles the mouse and the keyboard. Most of it is merely to pass information
  70.  * to the keyboard and pointer devices. This could be done more cleanly by
  71.  * repeating the ioctl to get the PM_Info.
  72.  */
  73. static PM_Info *    info;
  74. static pmEventQueue *    queue;
  75. static pmBox *        mbox;
  76. static pmCursor    *    mouse;
  77. static char *        bitmap;
  78. static pmEvent *    events;
  79. static pmTimeCoord *    tcs;
  80. static int        fdPM;
  81. static int        qLimit;
  82. static int        lastEventTime;
  83. static DevicePtr    pmKeyboard;
  84. static DevicePtr    pmPointer;
  85. static int        hotX, hotY;
  86. static BoxRec        cursorRange, cursorConstraint;
  87. static int         mapOnce = 0;
  88. static int        dpix = -1, dpiy = -1, dpi = -1;
  89. static Bool         SpecificB, SpecificW;
  90. static char        *blackValue, *whiteValue;
  91.  
  92. #define MAX_LED 4
  93.  
  94. /* what is this and what does it do ??? */
  95. xColorItem        screenWhite, screenBlack;
  96.  
  97. /*
  98.  * Statics to contain the current value for the keyboard and pointer devices
  99.  */
  100.  
  101.  
  102. /* SaveScreen does blanking, so no need to worry about the interval timer */
  103.  
  104. static Bool
  105. pmSaveScreen(pScreen, on)
  106.     ScreenPtr pScreen;
  107.     int on;
  108. {
  109.     if (on != SCREEN_SAVER_ON)
  110.     {
  111.         lastEventTime = GetTimeInMillis();
  112.     if (ioctl(fdPM, QIOVIDEOON) < 0)
  113.         ErrorF("pmSaveScreen: failed to turn screen on.\n");
  114.     } else {
  115.     if (ioctl(fdPM, QIOVIDEOOFF) < 0)
  116.         ErrorF("pmSaveScreen: failed to turn screen off.\n");
  117.     }
  118.     return TRUE;
  119. }
  120.  
  121. Bool
  122. pmScreenInit(index, pScreen, argc, argv)
  123.     int index;
  124.     ScreenPtr pScreen;
  125.     int argc;
  126.     char **argv;
  127. {
  128.     register    PixmapPtr pPixmap;
  129.     ColormapPtr pColormap;
  130.     VisualPtr    pVisual;
  131.     int        i;
  132.     void    ddxUseMsg();
  133.  
  134.     if (mapOnce)
  135.     {
  136.     /*
  137.      * The reason you need to do this is so that when the
  138.      * the server recycles and the system is in video off
  139.      * state you need something to turn the video on.  Note
  140.      * that unlike the vaxstar you don't do a fresh open 
  141.      * and close of the device and thus the video remains
  142.      * off if you don't explicitly turn it on.
  143.      */
  144.     if (ioctl(fdPM, QIOVIDEOON) < 0)
  145.         ErrorF("pmSaveScreen: failed to turn screen on.\n");
  146.     }
  147.  
  148.     if (!mapOnce) 
  149.     {
  150.         if ((fdPM = open("/dev/mouse", O_RDWR | O_NDELAY, 0)) < 0)
  151.         {
  152.         ErrorF("couldn't open pm \n");
  153.         return FALSE;
  154.         }
  155.  
  156.        if (ioctl(fdPM, QIOCGINFO, &info) < 0)
  157.        {
  158.        ErrorF("error getting address of info\n");
  159.        close(fdPM);
  160.        return FALSE;
  161.        }
  162.         mapOnce = 1;
  163.     }
  164.  
  165.     queue = &((PM_Info *)info)->qe;
  166.     mbox = &((PM_Info *)info)->mbox;
  167.     mouse = &((PM_Info *)info)->mouse;
  168.     qLimit = queue->eSize - 1;
  169.     events = info->qe.events;
  170.     tcs = info->qe.tcs;
  171.     bitmap = info->bitmap;
  172.  
  173.     /* discard all the current input events  */
  174.     queue->eHead = queue->eTail;
  175.  
  176.     cursorRange.x1 = -15;
  177.     cursorRange.x2 = ((PM_Info *)info)->max_x - 1;
  178.     cursorRange.y1 = -15;
  179.     cursorRange.y2 = ((PM_Info *)info)->max_y - 1;
  180.  
  181.     if (dpi == -1) /* dpi has not been set */
  182.     {
  183.         if (dpix == -1) /* ie dpix has not been set */
  184.         {
  185.         if (dpiy == -1)
  186.         {
  187.             dpix = 78;
  188.             dpiy = 78;
  189.         }
  190.         else
  191.             dpix = dpiy;
  192.         }
  193.         else
  194.         { 
  195.         if (dpiy == -1)
  196.             dpiy = dpix;
  197.         }
  198.     }
  199.     else
  200.     {
  201.     dpix = dpi;
  202.     dpiy = dpi;
  203.     }
  204.  
  205.     /* video blanking screen saver */
  206.     pScreen->SaveScreen = pmSaveScreen;
  207.     /* pm cursor routines */
  208.     pScreen->RealizeCursor = pmRealizeCursor;
  209.     pScreen->UnrealizeCursor = pmUnrealizeCursor;
  210.     pScreen->DisplayCursor = pmDisplayCursor;
  211.     pScreen->SetCursorPosition = pmSetCursorPosition;
  212.     pScreen->CursorLimits = pmCursorLimits;
  213.     pScreen->PointerNonInterestBox = pmPointerNonInterestBox;
  214.     pScreen->ConstrainCursor = pmConstrainCursor;
  215.     pScreen->RecolorCursor = miRecolorCursor;
  216.  
  217.     for (i = 1; i < argc; i++ )
  218.     {
  219.         if(strncmp(argv[i], "-bp:", 4) == 0 && atoi(argv[i] + 4) == index)
  220.         {
  221.         if(++i < argc)
  222.         {
  223.         blackValue = argv[i];
  224.         SpecificB = TRUE;
  225.         }
  226.         else
  227.         ddxUseMsg();
  228.         }
  229.         if(strncmp(argv[i], "-wp:", 4) == 0 && atoi(argv[i] + 4) == index)
  230.         {
  231.         if(++i < argc)
  232.         {
  233.         whiteValue = argv[i];
  234.         SpecificW = TRUE;
  235.         }
  236.         else
  237.         ddxUseMsg();
  238.         }
  239.     }
  240.  
  241.     pScreen->blackPixel = 0;
  242.     pScreen->whitePixel = 1;
  243.  
  244.     if(blackValue)
  245.     {
  246.     if((i = atoi(blackValue)) == 0 || i == 1)
  247.         pScreen->blackPixel = i;
  248.     else  
  249.         pmPixelError(index);
  250.     }
  251.     if(whiteValue)
  252.     {
  253.         if((i = atoi(whiteValue)) == 0 || i == 1)
  254.             pScreen->whitePixel = i;
  255.         else  
  256.         pmPixelError(index);
  257.     }
  258.  
  259.     if (!mfbScreenInit(pScreen, (char *)bitmap, 
  260.                 ((PM_Info *)info)->max_x, 
  261.                 ((PM_Info *)info)->max_y, dpix, dpiy, 2048))
  262.     {
  263.     close (fdPM);
  264.     return FALSE;
  265.     }
  266.  
  267.     /*
  268.      * pmQueryBestSize also knows about cursor sizes, mash
  269.      * the mfb suplied version
  270.      */
  271.     pScreen->QueryBestSize = pmQueryBestSize;
  272.     /*
  273.      * create and install the default colormap
  274.      */
  275.     if (!mfbCreateDefColormap (pScreen))
  276.     {
  277.     close (fdPM);
  278.     return FALSE;
  279.     }
  280.     return TRUE;
  281. }
  282.  
  283. pmPixelError(index)
  284. int    index;
  285. {
  286.     ErrorF("Only 0 or 1 are acceptable pixels for device %d\n", index);
  287. }
  288.  
  289. static void
  290. ChangeLED(led, on)
  291.     int led;
  292.     Bool on ;
  293. {
  294.     struct pm_kpcmd ioc;
  295.  
  296.     if (led > MAX_LED)    
  297.         return;
  298.     if (on)
  299.         ioc.cmd = LK_LED_ENABLE;
  300.     else
  301.         ioc.cmd = LK_LED_DISABLE;
  302.     if (led == 1)
  303.     ioc.par[0] = LED_1;
  304.     else if (led == 2)
  305.         ioc.par[0] = LED_2;
  306.     else if (led == 3)
  307.         ioc.par[0] = LED_3;
  308.     else if (led == 4)
  309.         ioc.par[0] = LED_4;
  310.     ioc.par[1]  = 0;
  311.     ioc.nbytes = 1;
  312.     ioctl(fdPM, QIOCKPCMD, &ioc);
  313. }
  314.  
  315. static void
  316. pmChangeKeyboardControl(device, ctrl)
  317.     DevicePtr device;
  318.     KeybdCtrl *ctrl;
  319. {
  320. #define LK_ENABLE_CLICK 0x1b    /* enable keyclick / set volume    */
  321. #define LK_DISABLE_CLICK 0x99    /* disable keyclick entirely    */
  322. #define LK_ENABLE_BELL 0x23    /* enable bell / set volume     */
  323.  
  324.     struct pm_kpcmd ioc;
  325.     int i;
  326.  
  327.     if (ctrl->click == 0)    /* turn click off */
  328.     {
  329.     ioc.nbytes = 0;
  330.     ioc.cmd = LK_DISABLE_CLICK;
  331.     ioctl(fdPM, QIOCKPCMD, &ioc);
  332.     }
  333.     else 
  334.     {
  335.         int volume;
  336.  
  337.         volume = 7 - ((ctrl->click / 14) & 7);
  338.     ioc.nbytes = 1;
  339.     ioc.cmd = LK_ENABLE_CLICK;
  340.     ioc.par[0] = volume;
  341.     ioctl(fdPM, QIOCKPCMD, &ioc);
  342.     }
  343.  
  344.     /* ctrl->bell: the DIX layer handles the base volume for the bell */
  345.     
  346.     /* ctrl->bell_pitch: as far as I can tell, you can't set this on lk201 */
  347.  
  348.     /* ctrl->bell_duration: as far as I can tell, you can't set this  */
  349.  
  350.     /* LEDs */
  351.     for (i=1; i<=MAX_LED; i++)
  352.         ChangeLED(i, (ctrl->leds & (1 << (i-1))));
  353.  
  354.     /* ctrl->autoRepeat: I'm turning it all on or all off.  */
  355.  
  356.     SetLKAutoRepeat(ctrl->autoRepeat);
  357. }
  358.  
  359. static void
  360. pmBell(loud, pDevice)
  361.     int loud;
  362.     DevicePtr pDevice;
  363. {
  364.     struct pm_kpcmd ioc;
  365.  
  366. /* the lk201 volume is between 7 (quiet but audible) and 0 (loud) */
  367.     loud = 7 - ((loud / 14) & 7);
  368.     ioc.nbytes = 1;
  369.     ioc.cmd = LK_BELL_ENABLE;
  370.     ioc.par[0] = loud;
  371.     ioctl(fdPM, QIOCKPCMD, &ioc);
  372.  
  373.     ioc.nbytes = 0;
  374.     ioc.cmd = LK_RING_BELL;
  375.     ioctl(fdPM, QIOCKPCMD, &ioc);
  376. }
  377.  
  378. /*
  379.  * These serve protocol requests, setting/getting acceleration and threshold.
  380.  * X10 analog is "SetMouseCharacteristics".
  381.  */
  382. static void
  383. pmChangePointerControl(device, ctrl)
  384.     DevicePtr device;
  385.     PtrCtrl   *ctrl;
  386. {
  387.     ((PM_Info *)info)->mthreshold = ctrl->threshold;
  388.     if (!(((PM_Info *)info)->mscale = ctrl->num / ctrl->den))
  389.     ((PM_Info *)info)->mscale = 1;    /* watch for den > num */
  390. }
  391.  
  392. static int
  393. pmGetMotionEvents(pDevice, buff, start, stop)
  394.     CARD32 start, stop;
  395.     DevicePtr pDevice;
  396.     xTimecoord *buff;
  397. {
  398.     int count = 0;
  399.     int tcFirst = queue->tcNext;
  400.     int tcLast = (tcFirst) ? tcFirst - 1 : queue->tcSize - 1;
  401.     register pmTimeCoord *Tcs;
  402.     int i;
  403.  
  404.     for (i == tcFirst; ; i++)
  405.     {
  406.     if (i = queue->tcSize)
  407.     i = 0;
  408.     Tcs = &((pmTimeCoord *)tcs)[i];
  409.     if ((start <= Tcs->time) && (Tcs->time <= stop))
  410.     {
  411.     buff[count].time = Tcs->time;
  412.     buff[count].x = Tcs->x;
  413.     buff[count].y = Tcs->y;
  414.     count++;
  415.     }
  416.     if (i == tcLast)
  417.     return count;
  418.     }
  419. }
  420.  
  421. int
  422. pmMouseProc(pDev, onoff, argc, argv)
  423.     DevicePtr pDev;
  424.     int onoff, argc;
  425.     char *argv[];
  426. {
  427.     int     i;
  428.     BYTE    map[4];
  429.  
  430.     switch (onoff)
  431.     {
  432.     case DEVICE_INIT: 
  433.         pmPointer = pDev;
  434.         pDev->devicePrivate = (pointer) &queue;
  435.         map[1] = 1;
  436.         map[2] = 2;
  437.         map[3] = 3;
  438.         InitPointerDeviceStruct(
  439.         pmPointer, map, 3, pmGetMotionEvents, pmChangePointerControl,
  440.         MOTION_BUFFER_SIZE);
  441.         SetInputCheck(&queue->eHead, &queue->eTail);
  442.         hotX = hotY = 0;
  443.         break;
  444.     case DEVICE_ON: 
  445.         pDev->on = TRUE;
  446.         AddEnabledDevice(fdPM);
  447.         break;
  448.     case DEVICE_OFF: 
  449.         pDev->on = FALSE;
  450.         RemoveEnabledDevice(fdPM);
  451.         break;
  452.     case DEVICE_CLOSE:
  453.         break;
  454.     }
  455.     return Success;
  456. }
  457.  
  458. #define LK_REPEAT_ON  0xe3
  459. #define LK_REPEAT_OFF 0xe1
  460.  
  461. int
  462. SetLKAutoRepeat (onoff)
  463.     Bool onoff;
  464. {
  465.     extern char *AutoRepeatLKMode();
  466.     extern char *UpDownLKMode();
  467.     
  468.     struct pm_kpcmd ioc;
  469.     register char  *divsets;
  470.     divsets = onoff ? (char *) AutoRepeatLKMode() : (char *) UpDownLKMode();
  471.     ioc.nbytes = 0;
  472.     while (ioc.cmd = *divsets++)
  473.     ioctl(fdPM, QIOCKPCMD, &ioc);
  474.     ioc.cmd = ((onoff > 0) ? LK_REPEAT_ON : LK_REPEAT_OFF);
  475.     return(ioctl(fdPM, QIOCKPCMD, &ioc));
  476. }
  477.  
  478. int
  479. pmKeybdProc(pDev, onoff, argc, argv)
  480.     DevicePtr pDev;
  481.     int onoff, argc;
  482.     char *argv[];
  483. {
  484.     KeySymsRec keySyms;
  485.     CARD8 modMap[MAP_LENGTH];
  486.  
  487.     switch (onoff)
  488.     {
  489.     case DEVICE_INIT: 
  490.         pmKeyboard = pDev;
  491.         pDev->devicePrivate = (pointer) & queue;
  492.         GetLK201Mappings( &keySyms, modMap);
  493.         InitKeyboardDeviceStruct(
  494.             pmKeyboard, &keySyms, modMap, pmBell,
  495.             pmChangeKeyboardControl);
  496.         
  497.         /* Free the key sym mapping space allocated by GetLK201Mappings. */
  498.         Xfree(keySyms.map);
  499.  
  500.         break;
  501.     case DEVICE_ON: 
  502.         pDev->on = TRUE;
  503.         AddEnabledDevice(fdPM);
  504.         break;
  505.     case DEVICE_OFF: 
  506.         pDev->on = FALSE;
  507.         RemoveEnabledDevice(fdPM);
  508.         break;
  509.     case DEVICE_CLOSE: 
  510.         break;
  511.     }
  512.     return Success;
  513. }
  514.  
  515. /*
  516.  * The driver has been set up to put events in the queue that are identical
  517.  * in shape to the events that the DDX layer has to deliver to ProcessInput
  518.  * in DIX.
  519.  */
  520. extern int screenIsSaved;
  521.  
  522. void
  523. ProcessInputEvents()
  524. {
  525. #define DEVICE_KEYBOARD 2
  526.     pmEvent e;
  527.     xEvent x;
  528.     register int    i;
  529.  
  530.     i = queue->eHead;
  531.     while (i != queue->eTail)
  532.     {
  533.     if (screenIsSaved == SCREEN_SAVER_ON)
  534.         SaveScreens(SCREEN_SAVER_OFF, ScreenSaverReset);
  535.     e = *((pmEvent *) & ((pmEvent *)events)[i]);
  536.     x.u.keyButtonPointer.rootX = e.x + hotX;
  537.     x.u.keyButtonPointer.rootY = e.y + hotY;
  538.     x.u.keyButtonPointer.time = lastEventTime = e.time;
  539.     x.u.u.detail = e.key;
  540.  
  541.     if (e.device == DEVICE_KEYBOARD)
  542.     {
  543.         switch (e.type)
  544.         {
  545.         case BUTTON_DOWN_TYPE: 
  546.             x.u.u.type = KeyPress;
  547.             (*pmKeyboard->processInputProc) (&x, pmKeyboard, 1);
  548.             break;
  549.         case BUTTON_UP_TYPE: 
  550.             x.u.u.type = KeyRelease;
  551.             (*pmKeyboard->processInputProc) (&x, pmKeyboard, 1);
  552.             break;
  553.         default:            /* hopefully BUTTON_RAW_TYPE */
  554.             ProcessLK201Input(&x, pmKeyboard);
  555.         }
  556.     }
  557.     else
  558.     {
  559.         switch (e.type)
  560.         {
  561.         case BUTTON_DOWN_TYPE: 
  562.             x.u.u.type = ButtonPress;
  563.             break;
  564.         case BUTTON_UP_TYPE: 
  565.             x.u.u.type = ButtonRelease;
  566.             break;
  567.         case MOTION_TYPE: 
  568.             x.u.u.type = MotionNotify;
  569.             break;
  570.         default: 
  571.             FatalError("Unknown event from mouse driver");
  572.         }
  573.         (*pmPointer->processInputProc) (&x, pmPointer, 1);
  574.     }
  575.  
  576.     if (i == qLimit){
  577.         i = queue->eHead = 0;
  578.     }else{
  579.         i = ++queue->eHead;
  580.     }
  581.     }
  582. #undef DEVICE_KEYBOARD
  583. }
  584.  
  585. TimeSinceLastInputEvent()
  586. {
  587.     if (lastEventTime == 0)
  588.     lastEventTime = GetTimeInMillis();
  589.     return GetTimeInMillis() - lastEventTime;
  590. }
  591.  
  592. /*
  593.  * set the bounds in the device for this particular cursor
  594.  */
  595. static void
  596. pmConstrainCursor( pScr, pBox)
  597.     ScreenPtr    pScr;
  598.     BoxPtr    pBox;
  599. {
  600.     cursorConstraint = *pBox;
  601.     if (((PM_Info *)info))
  602.     {
  603.     ((PM_Info *)info)->max_cur_x = pBox->x2 - hotX - 1;
  604.     ((PM_Info *)info)->max_cur_y = pBox->y2 - hotY - 1;
  605.     ((PM_Info *)info)->min_cur_x = pBox->x1 - hotX;
  606.     ((PM_Info *)info)->min_cur_y = pBox->y1 - hotY;
  607.     }
  608. }
  609.  
  610. static Bool
  611. pmSetCursorPosition( pScr, newx, newy, generateEvent)
  612.     ScreenPtr        pScr;
  613.     unsigned int    newx, newy;
  614.     Bool        generateEvent;
  615. {
  616.     pmCursor    pmCPos;
  617.     xEvent    motion;
  618.  
  619.     pmCPos.x = (short)((int)newx - hotX);
  620.     pmCPos.y = (short)((int)newy - hotY);
  621.  
  622.     if ( ioctl(fdPM, QIOCPMSTATE, &pmCPos) < 0)
  623.     {
  624.     ErrorF( "error warping cursor\n");
  625.     return FALSE;
  626.     }
  627.     if (generateEvent)
  628.     {
  629.     if (queue->eHead != queue->eTail)
  630.         ProcessInputEvents();
  631.     motion.u.keyButtonPointer.rootX = newx;
  632.     motion.u.keyButtonPointer.rootY = newy;
  633.     motion.u.keyButtonPointer.time = currentTime.milliseconds;
  634.     motion.u.u.type = MotionNotify;
  635.     (*pmPointer->processInputProc) (&motion, pmPointer, 1);
  636.     }
  637.  
  638.     return TRUE;
  639. }
  640.  
  641. static Bool
  642. pmDisplayCursor( pScr, pCurs)
  643.     ScreenPtr    pScr;
  644.     CursorPtr    pCurs;
  645. {
  646.     int        x, y;
  647.     /*
  648.      * load the cursor
  649.      */
  650.     if ((hotX != pCurs->bits->xhot) || (hotY != pCurs->bits->yhot))
  651.     {
  652.     x = (int)mouse->x + hotX;
  653.     y = (int)mouse->y + hotY;
  654.     hotX = pCurs->bits->xhot;
  655.     hotY = pCurs->bits->yhot;
  656.     pmSetCursorPosition(pScr, x, y, FALSE);
  657.     pmConstrainCursor(pScr, &cursorConstraint);
  658.         /* to update constraints in driver */
  659.     }
  660.     if ( ioctl( fdPM, QIOWCURSOR, pCurs->devPriv[ pScr->myNum]) < 0)
  661.     {
  662.     ErrorF( "error loading bits of new cursor\n");
  663.         return FALSE;
  664.     }
  665.     return TRUE;
  666. }
  667.  
  668. /*
  669.  */
  670. static Bool
  671. pmRealizeCursor( pScr, pCurs)
  672.     ScreenPtr    pScr;
  673.     CursorPtr    pCurs;    /* a SERVER-DEPENDENT cursor */
  674. {
  675.     int    forecolor =
  676.      ( pCurs->foreRed || pCurs->foreGreen || pCurs->foreBlue)?~0:0;
  677.     int    backcolor = ~forecolor;
  678.     register short    *a, *b;    /* vaxstar-defined */
  679.     register int *    mask;    /* server-defined */
  680.     register int *    src;    /* server-defined */
  681.     int        i;
  682.     int        cursorBytes = 32*sizeof(unsigned short);
  683.     int        lastRow = ((pCurs->bits->height < 16) ? pCurs->bits->height : 16);
  684.     register unsigned short widthmask = (1<<pCurs->bits->width)-1;
  685.                 /* used to mask off beyond the edge of the
  686.                    real mask and source bits
  687.                 */
  688.  
  689.     pCurs->devPriv[ pScr->myNum] = (pointer)Xalloc(cursorBytes);
  690.     bzero((char *)pCurs->devPriv[ pScr->myNum], cursorBytes);
  691.  
  692.     /*
  693.      * munge the SERVER-DEPENDENT, device-independent cursor bits into
  694.      * what the device wants, which is 32 contiguous shorts.
  695.      *
  696.      * cursor hardware has "A" and "B" bitmaps
  697.      * logic table is:
  698.      *
  699.      *        A    B    cursor
  700.      *
  701.      *        0    0    transparent
  702.      *        1    0    xor (not used)
  703.      *        0    1    black
  704.      *        1    1    white
  705.      */
  706.  
  707.     /*
  708.      * "a" bitmap = image 
  709.      */
  710.     /*
  711.      * "b" bitmap can be same as "mask", providing "a" is never on when
  712.      *  "b" is off.
  713.      */
  714.     for ( i=0,
  715.       a = (short *)pCurs->devPriv[pScr->myNum],
  716.       b = ((short *)pCurs->devPriv[pScr->myNum]) + 16,
  717.     /* XXX assumes server bitmap pad is size of int, 
  718.        and cursor is < 32 bits wide */
  719.       src = (int *)pCurs->bits->source,
  720.       mask = (int *)pCurs->bits->mask;
  721.  
  722.       i < lastRow;
  723.  
  724.       i++, a++, b++, src++, mask++)
  725.     {
  726.     *a = ((*src & forecolor) | (~*src & backcolor)) & *mask;
  727.     *b = *mask;
  728.     *a &= widthmask;
  729.     *b &= widthmask;
  730.     }
  731.     return TRUE;
  732. }
  733.  
  734. static Bool
  735. pmUnrealizeCursor( pScr, pCurs)
  736.     ScreenPtr    pScr;
  737.     CursorPtr    pCurs;
  738. {
  739.     Xfree( pCurs->devPriv[ pScr->myNum]);
  740.     return TRUE;
  741. }
  742.  
  743. static void
  744. pmPointerNonInterestBox( pScr, pBox)
  745.     ScreenPtr    pScr;
  746.     BoxPtr    pBox;
  747. {
  748.     ((PM_Info *)info)->mbox.bottom = pBox->y2;
  749.     ((PM_Info *)info)->mbox.top = pBox->y1;
  750.     ((PM_Info *)info)->mbox.left = pBox->x1;
  751.     ((PM_Info *)info)->mbox.right = pBox->x2;
  752. }
  753.  
  754. /*
  755.  * pm cursor top-left corner can now go to negative coordinates
  756.  */
  757. static void
  758. pmCursorLimits( pScr, pCurs, pHotBox, pPhysBox)
  759.     ScreenPtr    pScr;
  760.     CursorPtr    pCurs;
  761.     BoxPtr    pHotBox;
  762.     BoxPtr    pPhysBox;    /* return value */
  763. {
  764.     pPhysBox->x1 = max( pHotBox->x1, cursorRange.x1 + (int) pCurs->bits->xhot);
  765.     pPhysBox->y1 = max( pHotBox->y1, cursorRange.y1 + (int) pCurs->bits->yhot);
  766.     pPhysBox->x2 = min( pHotBox->x2, cursorRange.x2 + 1);
  767.     pPhysBox->y2 = min( pHotBox->y2, cursorRange.y2 + 1);
  768. }
  769.  
  770. static void
  771. pmQueryBestSize(class, pwidth, pheight)
  772.     int class;
  773.     short *pwidth;
  774.     short *pheight;
  775. {
  776.     unsigned width, test;
  777.  
  778.     if (*pwidth > 0)
  779.     {
  780.       switch(class)
  781.       {
  782.         case CursorShape:
  783.       *pwidth = 16;
  784.       *pheight = 16;
  785.       break;
  786.         case TileShape:
  787.         case StippleShape:
  788.       width = *pwidth;
  789.       /* Return the closes power of two not less than what they gave me */
  790.       test = 0x80000000;
  791.       /* Find the highest 1 bit in the width given */
  792.       while(!(test & width))
  793.          test >>= 1;
  794.       /* If their number is greater than that, bump up to the next
  795.        *  power of two */
  796.       if((test - 1) & width)
  797.          test <<= 1;
  798.       *pwidth = test;
  799.       /* We don't care what height they use */
  800.       break;
  801.        }
  802.     }
  803. }
  804.  
  805. SetLockLED (on)
  806.     Bool on;
  807.     {
  808.     struct pm_kpcmd ioc;
  809.     ioc.cmd = on ? LK_LED_ENABLE : LK_LED_DISABLE;
  810.     ioc.par[0] = LED_3;
  811.     ioc.par[1] = 0;
  812.     ioc.nbytes = 1;
  813.     ioctl(fdPM, QIOCKPCMD, &ioc);
  814.     }
  815.  
  816. /*
  817.  * DDX - specific abort routine.  Called by AbortServer().
  818.  */
  819. void
  820. AbortDDX()
  821. {
  822. }
  823.  
  824. /* Called by GiveUp(). */
  825. void
  826. ddxGiveUp()
  827. {
  828. }
  829.  
  830. int
  831. ddxProcessArgument (argc, argv, i)
  832.     int argc;
  833.     char *argv[];
  834.     int i;
  835. {
  836.     int            argind=i;
  837.     int            skip;
  838.     static int        Once=0;
  839.     void        ddxUseMsg();
  840.  
  841.     skip = 0;
  842.     if (!Once)
  843.     {
  844.         blackValue = NULL;
  845.         SpecificB = FALSE;
  846.         whiteValue = NULL;
  847.         SpecificW = FALSE;
  848.     Once = 1;
  849.     }
  850.  
  851.     if (strcmp( argv[argind], "-dpix") == 0)
  852.     {
  853.     if (++argind < argc)
  854.     {
  855.         dpix = atoi(argv[argind]);
  856.         skip = 2;
  857.     }
  858.     else
  859.     {
  860.         ddxUseMsg();
  861.         skip = 1;
  862.     }
  863.     }
  864.     else if (strcmp( argv[argind], "-dpiy") == 0)
  865.     {
  866.     if (++argind < argc)
  867.     {
  868.         dpiy = atoi(argv[argind]);
  869.         skip = 2;
  870.     }
  871.     else
  872.     {
  873.         ddxUseMsg();
  874.         skip = 1;
  875.     }
  876.     }
  877.     else if (strcmp( argv[argind], "-dpi") == 0)
  878.     {
  879.     if (++argind < argc)
  880.     {
  881.         dpi = atoi(argv[argind]);
  882.         dpix = dpi;
  883.         dpiy = dpi;
  884.         skip = 2;
  885.     }
  886.     else
  887.     {
  888.         ddxUseMsg();
  889.         skip = 1;
  890.     }
  891.     }
  892.     else 
  893.     if(strcmp(argv[argind], "-bp") == 0 && !SpecificB)
  894.     {
  895.         if(++argind < argc)
  896.         {
  897.         blackValue = argv[argind];
  898.         skip = 2;
  899.         }
  900.         else
  901.         {
  902.         ddxUseMsg();
  903.         skip = 1;
  904.         }
  905.     }
  906.     else
  907.     if(strcmp(argv[argind], "-wp") == 0 && !SpecificW)
  908.     {
  909.         if(++argind < argc)
  910.         {
  911.         whiteValue = argv[argind];
  912.         skip = 2;
  913.         }
  914.         else
  915.         {
  916.         ddxUseMsg();
  917.         skip = 1;
  918.         }
  919.     }
  920.        
  921.     return skip;
  922.  
  923. }
  924.  
  925. void
  926. ddxUseMsg()
  927. {
  928.     ErrorF ("Device Dependent Usage\n");
  929.     ErrorF ("-dpi #        Dots per inch, x and y coordinates\n");
  930.     ErrorF ("-dpix #        Dots per inch, x coordinate\n");
  931.     ErrorF ("-dpiy #        Dots per inch, y coordinate\n");
  932.     ErrorF ("-bp color BlackPixel for screen\n");
  933.     ErrorF ("-wp color BlackPixel for screen\n");
  934. }
  935.